#include "OperatorFunctionNode.h"

#include "Output/Console.h"
#include "ScriptCompiler/Token/Token.h"
#include "ScriptCompiler/AST/TypeNode.h"
#include "ScriptCompiler/AST/AccessLevelNode.h"
#include "ScriptCompiler/AST/ParameterNode.h"
#include "ScriptCompiler/AST/SentenceBlockNode.h"
#include "ScriptCompiler/AST/ExpressionNode.h"
#include "ScriptCompiler/AST/DecoratorNode.h"

void COperatorFunctionNode::DebugPrint(int32_t InDepth)
{
    //print blank spaces for depth
    for(int32_t i=0;i<InDepth;i++)
    {
        WH::Print(U"\t");
    }

    //print access level
    if(AccessLevel.HasValue())
    {
        AccessLevel.GetValue()->DebugPrint(0);
        WH::Print(U" ");
    }

    if(Decorator.HasValue())
    {
        Decorator.GetValue()->DebugPrint(0);
        WH::Print(U" ");
    }

    //print return type
    ReturnType->DebugPrint(0);

    //print function name
    WH::Print(U" operator ");
    WH::Print(Operator->ToString());

    //print parameters
    WH::Print(U"(");
    for(auto& Parameter : Parameters)
    {
        Parameter->DebugPrint(0);
        WH::Print(U",");
    }
    WH::Print(U")\n");

    if(Content.HasValue())
    {
        //print { with depth
        for(int32_t i=0;i<InDepth;++i)
        {
            WH::Print(U"\t");
        }
        WH::Print(U"{\n");

        Content.GetValue()->DebugPrint(InDepth+1);

        //print } with depth
        for(int32_t i=0;i<InDepth;++i)
        {
            WH::Print(U"\t");
        }
        WH::Print(U"}\n");

    }
    else if(LambdaContent.HasValue())
    {
        //print =>
        WH::Print(U"=> ");

        //print lambda content
        LambdaContent.GetValue()->DebugPrint(0);

        WH::Print(U";\n");
    }
    else
    {
        WH::Print(U";\n");
    }

}

std::shared_ptr<CScriptToken> COperatorFunctionNode::GetFirstToken()
{
    if(AccessLevel.HasValue())
    {
        return AccessLevel.GetValue()->GetFirstToken();
    }
    else if(Decorator.HasValue())
    {
        return Decorator.GetValue()->GetFirstToken();
    }
    else
    {
        return ReturnType->GetFirstToken();
    }
}
